package abg.core.service.sys.impl;


import abg.core.common.cache.Cache;
import abg.core.common.security.AuthKit;
import abg.core.common.security.AuthUser;
import abg.core.common.util.IdKit;
import abg.core.common.util.ObjectKit;
import abg.core.common.util.StringKit;
import abg.core.domain.db.SysOrg;
import abg.core.domain.db.SysOrgMenu;
import abg.core.domain.sys.MSG;
import abg.core.domain.sys.ServiceException;
import abg.core.mapper.SysOrgMapper;
import abg.core.mapper.SysOrgMenuMapper;
import abg.core.service.sys.SysOrgService;
import abg.core.service.sys.SysResService;
import com.alibaba.fastjson2.JSONArray;
import com.mybatisflex.core.query.QueryWrapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import static abg.core.domain.db.table.SysOrgTableDef.SYS_ORG;


/**
 * 组织机构实现
 */
@Slf4j
@Service
public class SysOrgServiceImpl implements SysOrgService {

    @Resource
    private Cache<String> cache;

    @Resource
    private SysOrgMapper sysOrgMapper;

    @Resource
    private SysOrgMenuMapper sysOrgMenuMapper;

    @Resource
    @Lazy
    private SysResService sysResService;


    @Override
    public boolean insert(SysOrg param) {
        param.setId(IdKit.getId());
        if (StringKit.isBlank(param.getPid())) param.setPid("0");

        //遍历树结构
        JSONArray ids = getTreeIds(param.getId(), param.getPid());
        param.setTreePath(ids.toString());

        int i = sysOrgMapper.insertSelective(param);

        return true;
    }

    //修改部门信息,更新部门权限
    @Override
    public boolean updateOrg(SysOrg param) {
        SysOrg sysOrg = ObjectKit.copyToNew(param, "id", "pid", "level", "name", "filePath", "sort", "res", "resExclude", "isDisable");

        //遍历树结构
        JSONArray ids = getTreeIds(param.getId(), param.getPid());
        sysOrg.setTreePath(ids.toString());

        int i = sysOrgMapper.update(sysOrg);

        //TODO 更新部门权限
        sysResService.refreshOrgResCache(sysOrg.getId());

        return true;
    }


    //更新库表中，部门关联的菜单
    //刷新部门具备资源缓存
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateOrgMenu(String orgId, String menuIds) {
        ArrayList<String> menuIdList = StringKit.split(menuIds);
        if (menuIdList.size() == 0) throw new ServiceException(MSG.PARAM_ER);

        QueryWrapper where = QueryWrapper.create().select("id").where("id = ?", orgId);
        if (sysOrgMapper.selectOneByQuery(where) == null) throw new ServiceException(MSG.ROLE_NOT_EXISTS);

        //删除
        long delCount = sysOrgMenuMapper.deleteByQuery(QueryWrapper.create().eq("org_id", orgId));

        //插入
        ArrayList<SysOrgMenu> insertList = new ArrayList<>(menuIdList.size());
        for (String menuId : menuIdList) {
            SysOrgMenu lkOrgMenu = new SysOrgMenu();
            lkOrgMenu.setOrgId(orgId);
            lkOrgMenu.setMenuId(menuId);
            insertList.add(lkOrgMenu);
        }
        long insertCount = sysOrgMenuMapper.insertBatch(insertList);

        //TODO 更新部门权限
        sysResService.refreshOrgResCache(orgId);

        return true;
    }


    //删除部门
    @Override
    public boolean delete(String ids) {
        ArrayList<String> split = StringKit.split(ids);

        int i = sysOrgMapper.deleteBatchByIds(split);

        //清权限
        for (String orgId : split) {
            sysResService.refreshOrgResCache(orgId);
        }
        return true;
    }

    //根据ID和PID查库，返回树结构JSON数组 ["PID-0","PID-01","自身ID"]
    @Override
    public JSONArray getTreeIds(String nowId, String pid) {
        JSONArray treeIds = new JSONArray();
        treeIds.add(nowId);
        if (!"0".equals(pid)) {
            do {
                QueryWrapper wrapper = new QueryWrapper();
                wrapper.select("id", "pid").from(SysOrg.class).where("id = ?", pid);
                SysOrg sysOrg = sysOrgMapper.selectOneByQuery(wrapper);
                if (sysOrg != null) {
                    pid = sysOrg.getPid();
                    treeIds.add(0, sysOrg.getId());
                }
            } while (pid != null && !pid.equals("0"));
        }
        return treeIds;
    }

    //系统中全部组织机构数据
    @Override
    public List<SysOrg> allOrg() {
        QueryWrapper wrapper = QueryWrapper.create().select("*").from(SYS_ORG).orderBy(SYS_ORG.SORT.asc()).orderBy(SYS_ORG.CT.desc());
        List<SysOrg> orgAllList = sysOrgMapper.selectListByQuery(wrapper);

        //填充MenuIDS
        for (SysOrg org : orgAllList) {
            QueryWrapper queryMenuIds = QueryWrapper.create().select("menu_id").where("org_id = ?", org.getId());
            List<Object> menuIds = sysOrgMenuMapper.selectObjectListByQuery(queryMenuIds);
            org.setMenuIds(menuIds);
        }
        return orgAllList;
    }

    //返回已登录用户具备的组织机构
    public List<SysOrg> userHasOrg() {
        AuthUser currentUser = AuthKit.mastLogin();
        //全部组织机构
        List<SysOrg> allOrgList = allOrg();
        //root直接返回所有
        if (currentUser.isRoot()) return allOrgList;

        //用户具备的组织机构
        List<String> userHasOrgIds = currentUser.getOrgIds();
        if (userHasOrgIds.size() == 0) return new ArrayList<>();
        List<SysOrg> sysOrgs = allOrgList.stream().filter(e -> userHasOrgIds.contains(e.getId())).toList();
        if (sysOrgs.size() == 0) return new ArrayList<>();

        //根据TreePath获取用户全路径数据
        HashSet<String> haseTreeIds = new HashSet<>();
        List<String> treePathList = sysOrgs.stream().map(SysOrg::getTreePath).toList();
        treePathList.forEach(e -> {
            haseTreeIds.addAll(JSONArray.parseArray(e).toList(String.class));
        });
        return allOrgList.stream().filter(e -> haseTreeIds.contains(e.getId())).toList();
    }


    //给该部门，添加此菜单的权限
//    private void addRoleMenu(List<String> roleIds, String menuId) {
//        for (String roleId : roleIds) {
//            SysOrgMenu lkRoleMenu = new SysOrgMenu();
//            lkRoleMenu.setRoleId(roleId);
//            lkRoleMenu.setMenuId(menuId);
//            try {
//                sysRoleMenuMapper.insertSelectiveWithPk(lkRoleMenu);
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        }
//    }

}
